local Tabledump = require("Tabledump")
local BattleMapConfig = require("BattleMapConfig")
-- local FightPto = require("FightPto")
local FUBEN_POSINDEX_BEGIN = require("BattleConst").FUBEN_POSINDEX_BEGIN

local BattleMap = {}
BattleMap.__index = BattleMap

-- 构造函数 new(t)
-- 功能: 初始化 BattleMap 对象。
-- 细节:
-- 从 BattleMapConfig 中获取指定类型 t 的配置。
-- 初始化 _isLoop 和 _routeList。
-- 对于每个路线，计算并存储路线段的信息，包括起点、终点、方向和长度。
function BattleMap:new(t)
    local self = setmetatable({}, BattleMap)
    -- Tabledump.dump( "BattleMap:new-t",t)
    -- local config = BattleMapConfig["COOP"]
    local config = BattleMapConfig[t]
    self._isLoop = config.isLoop
    self._routeList = {}

    for _, route in ipairs(config.routeList) do
        local segmentCount = #route.points
        local pointList = config.pointList
        local startPos = pointList[route.points[1]]
        local endPos = pointList[route.points[segmentCount]]
        local routeData = {
            fighterPosList = route.fighterPosList,
            fubenPosList = route.fubenPosList,
            startPos = startPos,
            endPos = endPos,
            points = route.points,
            totalLength = 0,
            segments = {}
        }

        for index, point in ipairs(route.points) do
            local currentPos = pointList[point]
            local nextPos = pointList[route.points[index + 1]]

            if nextPos then
                local dx = nextPos.x - currentPos.x
                local dy = nextPos.y - currentPos.y

                if dx ~= 0 and dy ~= 0 then
                    print("route point error")
                end

                local direction = dx ~= 0 and (dx >= 0 and 1 or -1) or (dy >= 0 and 1 or -1)
                local length = dx ~= 0 and math.abs(dx) or math.abs(dy)

                local segment = {
                    startPos = currentPos,
                    endPos = nextPos,
                    direction = direction,
                    length = length
                }

                table.insert(routeData.segments, segment)
                routeData.totalLength = routeData.totalLength + length
            end
        end

        table.insert(self._routeList, routeData)
    end

    return self
end
-- 功能: 检查地图是否是循环的。
-- 返回值: 布尔值，表示地图是否循环。
function BattleMap:isLoop()
    return self._isLoop
end
-- 功能: 获取最大战斗单位组数。
-- 返回值: 整数 18。
function BattleMap:getMaxFighterGroupNum()
    return 18
end
-- 功能: 获取路线上的战斗单位位置列表。
-- 参数: t 表示路线类型。
function BattleMap:getFighterPosList(t)
    return self:getRoute(t).fighterPosList
end
-- 功能: 获取某个类型 t 的路线索引。
-- 返回值: 如果是自己的战斗侧，返回 1，否则返回 2。
function BattleMap:getRouteIndex(t)
    -- return FightPto.getIns():isSelfBattleSide(t) and 1 or 2
    return t 
end
-- 功能: 获取指定类型 t 的路线数据。
-- 返回值: 路线对象。
function BattleMap:getRoute(t)
    local index = self:getRouteIndex(t)
    return self._routeList[index]
end
-- 功能: 根据索引获取路线。
-- 返回值: 路线对象。
function BattleMap:getRouteByIndex(index)
    return self._routeList[index]
end
-- 功能: 获取路线的起始位置。
-- 返回值: 起始位置坐标。
function BattleMap:getStartPos(t)
    return self:getRoute(t).startPos
end
-- 功能: 获取路线的结束位置。
-- 返回值: 结束位置坐标。
function BattleMap:getEndPos(t)
    return self:getRoute(t).endPos
end

-- 功能: 获取路线的总长度。
-- 返回值: 整数值，表示路线总长度。
function BattleMap:getTotalLength(t)
    return self:getRoute(t).totalLength
end
-- 功能: 根据距离获取位置信息。
-- 细节:
-- 计算给定位置 e 在路线上的坐标和方向。
-- 如果路线是循环的，距离 e 会取模。
function BattleMap:getPosInfoByLength(t, e)
    -- Tabledump.dump( "BattleMap:getPosInfoByLength-t",t)
    local route = self:getRoute(t)
    -- Tabledump.dump( "BattleMap:getPosInfoByLength route ",route)
    if self:isLoop() then
        e = e % route.totalLength
    end

    local position = {x = 0, y = 0}
    for _, segment in ipairs(route.segments) do
        if e < segment.length then
            if segment.startPos.x == segment.endPos.x then
                position.x = segment.startPos.x
                position.y = segment.startPos.y + segment.direction * e
            else
                position.x = segment.startPos.x + segment.direction * e
                position.y = segment.startPos.y
            end
            return { pos = position, direction = segment.direction }
        end
        e = e - segment.length
    end

    return { pos = route.endPos, direction = 1 }
end
-- 功能: 计算给定坐标 e 在路线上的距离。
-- 返回值: 距离值，或者 -1（如果坐标不在路线范围内）
function BattleMap:getDistanceByPos(t, e)
    local route = self:getRoute(t)
    local accumulatedDistance = 0

    for _, segment in ipairs(route.segments) do
        local length = segment.length

        if segment.startPos.x == segment.endPos.x then
            if e.x == segment.startPos.x then
                if segment.direction == 1 and e.y <= segment.endPos.y and e.y >= segment.startPos.y then
                    return accumulatedDistance + (e.y - segment.startPos.y)
                elseif segment.direction == -1 and e.y >= segment.endPos.y and e.y <= segment.startPos.y then
                    return accumulatedDistance + math.abs(e.y - segment.startPos.y)
                end
            end
        elseif e.y == segment.startPos.y then
            if segment.direction == 1 and e.x <= segment.endPos.x and e.x >= segment.startPos.x then
                return accumulatedDistance + (e.x - segment.startPos.x)
            elseif segment.direction == -1 and e.x >= segment.endPos.x and e.x <= segment.startPos.x then
                return accumulatedDistance + math.abs(e.x - segment.startPos.x)
            end
        end
        accumulatedDistance = accumulatedDistance + length
    end

    return -1
end
-- 功能: 根据距离获取方向角度。
-- 返回值: 角度值，0, 90, 180, 或 -90。
function BattleMap:getAngleByDistance(t, e)
    local route = self:getRoute(t)
    if self:isLoop() then
        e = e % route.totalLength
    end

    for _, segment in ipairs(route.segments) do
        if e < segment.length then
            if segment.startPos.x == segment.endPos.x then
                return segment.startPos.y < segment.endPos.y and 90 or -90
            else
                return segment.startPos.x < segment.endPos.x and 0 or 180
            end
        end
        e = e - segment.length
    end

    return 0
end
-- 功能: 获取指定位置索引 e 的网格坐标。
-- 细节:
-- 判断索引是否大于等于 FUBEN_POSINDEX_BEGIN。
-- 返回相应的 fubenPosList 或 fighterPosList 中的坐标。
function BattleMap:getGridPos(t, e)
    local route = self:getRoute(t)
    if e >= FUBEN_POSINDEX_BEGIN then
        return route.fubenPosList[e - FUBEN_POSINDEX_BEGIN]
    else
        return route.fighterPosList[e]
    end
end

return BattleMap